package yawning.mew.equipment;

import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;

import yawning.mew.equipment.RawItem.Property;
import yawning.mew.util.URLFetcher;

public class Enchant {
	public int mSpellId;
	public int mEnchantId;
	public String mName;
	public String mDescription;

	public Map<Property,Integer> properties = new HashMap<Property,Integer>();

	private static final String XML_ENCHANTS_FILE = "/META-INF/enchants.xml";
	private static final String ELEMENT_ENCHANT = "enchant";
	private static final String ATTR_NAME = "name";
	private static final String ATTR_ENCHANTID = "enchantId";
	private static Map<Integer,Enchant> sEnchantsByEnchantId = new HashMap<Integer,Enchant>();

	@SuppressWarnings("serial")
	private static final Map<String, Property> sIntPropertiesByAttr = new HashMap<String, Property>() {{
		put("stamina", Property.STAMINA);
		put("agility", Property.AGILITY);
		put("strength", Property.STRENGTH);
		put("intellect", Property.INTELLECT);
		put("spirit", Property.SPIRIT);

		put("spellPower", Property.SPELL_POWER);
		put("attackPower", Property.ATTACK_POWER);
		put("hasteRating", Property.HASTE_RATING);
		put("critRating", Property.CRIT_RATING);
		put("expertiseRating", Property.EXPERTISE_RATING);
		put("hitRating", Property.HIT_RATING);
		put("dodgeRating", Property.DODGE_RATING);
		put("masteryRating", Property.MASTERY_RATING);
		put("parryRating", Property.PARRY_RATING);
		put("resilienceRating", Property.RESILIENCE_RATING);
		put("spellPenetration", Property.SPELL_PENETRATION);
		put("bonusArmor", Property.BONUS_ARMOR);

		put("procSpellId", Property.PROC_SPELL_ID);	// Somewhat of a misnomer since we use the enchant's id and not procs.

		put("professionId", Property.PROFESSION_ID);
		put("professionSkill", Property.PROFESSION_SKILL);
		// TODO: Profession info!
	}};

	public static Enchant getEnchantByEnchantId(int enchantId) {
		return getEnchantByEnchantId(enchantId, false);
	}

	public static Enchant getEnchantByEnchantId(int enchantId, boolean allowNull) {
		loadEnchants();

		Enchant rval = sEnchantsByEnchantId.get(enchantId);
		if (rval == null) {
			if (allowNull) {
				rval = new Enchant();
				rval.mEnchantId = enchantId;
			} else {
				throw new RuntimeException("Unsupported Enchant ID: " + enchantId);
			}
		}

		return rval;
	}

	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append(mName).append(" (").append(mEnchantId).append(") ");
		for (Entry<Property,Integer> e : properties.entrySet()) {
			sb.append('[').append(e.getKey()).append('=').append(e.getValue()).append(']');
		}

		return sb.toString();
	}

	private static void loadEnchants() {
		synchronized (sEnchantsByEnchantId) {
			if (sEnchantsByEnchantId.size() > 0) return;

			try {
				SAXBuilder builder = new SAXBuilder();
				InputStream is = XMLItemSource.class.getResourceAsStream(XML_ENCHANTS_FILE);
				Document doc = builder.build(is);
				Element root = doc.getRootElement();

				@SuppressWarnings("unchecked") List<Element> enchants = root.getChildren(ELEMENT_ENCHANT);
				for (Element e: enchants) {
					Enchant enchant = new Enchant();
					enchant.mName = e.getAttributeValue(ATTR_NAME);
					enchant.mEnchantId = Integer.parseInt(e.getAttributeValue(ATTR_ENCHANTID));
					// TODO: Set spell ID here as well if we end up needing it.

					for (Map.Entry<String,Property> entry : sIntPropertiesByAttr.entrySet()) {
						String attr = entry.getKey();
						Property property = entry.getValue();

						String val = e.getAttributeValue(attr);
						if (val != null) enchant.properties.put(property, Integer.parseInt(val));
					}

					if (sEnchantsByEnchantId.containsKey(enchant.mEnchantId)) {
						throw new RuntimeException("Duplicate enchant ID: " + enchant.mEnchantId);
					}

					sEnchantsByEnchantId.put(enchant.mEnchantId, enchant);
				}
			}
			catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
	}

	public static void main(String args[]) {
		try {
			// TODO: Rewrite this so that I can actually have a spiffy database. :(
			URL url = new URL("http://cata.wowhead.com/spells=11.333?filter=cr=21;crs=1;crv=30305");
			String page = URLFetcher.getInstance().fetchAsString(url);

		    // _[74189]={name_enus:'Enchant Boots - Earthen Vitality',icon:'Spell_Holy_GreaterHeal'};
		    Matcher m = Pattern.compile("_\\[(\\d+)\\]=\\{name_enus:'(.+?)',icon:'.+?'\\};").matcher(page);
		    while (m.find()) {
		    	url = new URL("http://cata.wowhead.com/spell=" + m.group(1));
		    	String p = URLFetcher.getInstance().fetchAsString(url);

			    // Enchant Item: <span class="q2">+30 Stamina and Minor Movement Speed</span>&nbsp;(4062)</td>
			    Matcher matcher = Pattern.compile("Enchant Item: <span class=\"q2\">(.+?)</span>&nbsp;\\((\\d+)\\)</td>").matcher(p);
			    if (matcher.find()) {
			    	System.out.println(m.group(1) + " : " + m.group(2) + " : " + matcher.group(2) + " : " + matcher.group(1));
			    }
			    else {
			    	System.out.println("Ignoring spell " + m.group(1) + " : " + m.group(2));
			    }
		    }
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}
}
